import axios from 'axios'
import type { AxiosInstance } from 'axios'
import { useOidcStore } from '@/stores/oidc'
import type { DeviceConfig } from '@/types/device'
import { AuthMode, getByUrlAsync } from '@/api/http-client'

const baseUrl = import.meta.env.VITE_DEVICE_SERVER_BASE_URL

export async function getNodeIdsAsync() {
  return await getByUrlAsync<string[]>(baseUrl + '/api/nodes/ids', AuthMode.Bearer)
}

export async function getConfigsAsync(nodeId: string) {
  return await getByUrlAsync<DeviceConfig[]>(
    baseUrl + '/api/device-configs/' + nodeId,
    AuthMode.Bearer
  )
}

interface DefaultHttpRequestResult {
  message: string
  isSuccess: boolean
}

interface HttpRequestResult<TResult> extends DefaultHttpRequestResult {
  result: TResult
}

interface Target<TTask> {
  deviceId: string
  task: TTask
}

interface ReadValueTask {
  deviceName: string
  address: string
  dataType: string
}

interface WriteValueTask extends ReadValueTask {
  value: string
}

interface DeviceConfigTask {
  deviceConfigs: DeviceConfig[]
}

export class DeviceServerClient {
  private currentAxios: AxiosInstance

  private baseUrl: string

  /**
   * 默认构造函数
   */
  constructor(baseUrl: string) {
    this.baseUrl = baseUrl
    this.currentAxios = axios.create()
  }

  // 将配置更新到设备
  public async configAsync(target: Target<DeviceConfigTask>) {
    const oidcStore = useOidcStore()

    if (!oidcStore.isLogin) {
      return await Promise.resolve<DefaultHttpRequestResult>({
        isSuccess: false,
        message: '用户未登录！'
      })
    }

    try {
      const response = await this.currentAxios.put(this.baseUrl + '/api/device/config', target, {
        headers: {
          Authorization: oidcStore.getBearerToken()
        }
      })
      return response.data as DefaultHttpRequestResult
    } catch (error) {
      console.error(error)
      return await Promise.resolve<DefaultHttpRequestResult>({
        isSuccess: false,
        message: '配置设备错误！'
      })
    }
  }

  // 数据写入到 PLC
  public async writeValueAsync(target: Target<WriteValueTask>) {
    const oidcStore = useOidcStore()

    if (!oidcStore.isLogin) {
      return await Promise.resolve<HttpRequestResult<string>>({
        isSuccess: false,
        result: '',
        message: '用户未登录！'
      })
    }

    try {
      const response = await this.currentAxios.post(this.baseUrl + '/api/device/write', target, {
        headers: {
          Authorization: oidcStore.getBearerToken()
        }
      })
      return response.data as HttpRequestResult<string>
    } catch (error) {
      console.error(error)
      return await Promise.resolve<HttpRequestResult<string>>({
        isSuccess: false,
        result: '',
        message: '写入数据时错误！'
      })
    }
  }

  // 从 PLC 读取数据
  public async readValueAsync(target: Target<ReadValueTask>) {
    const oidcStore = useOidcStore()

    if (!oidcStore.isLogin) {
      return await Promise.resolve<HttpRequestResult<string>>({
        isSuccess: false,
        result: '',
        message: '用户未登录！'
      })
    }

    try {
      const response = await this.currentAxios.post(
        this.baseUrl + '/api/device/read-value',
        target,
        {
          headers: {
            Authorization: oidcStore.getBearerToken()
          }
        }
      )
      return response.data as HttpRequestResult<string>
    } catch (error) {
      console.error(error)
      return await Promise.resolve<HttpRequestResult<string>>({
        isSuccess: false,
        result: '',
        message: '读取数据时错误！'
      })
    }
  }

  // 删除一个配置
  public async deleteDeviceConfigAsync(id: string) {
    const oidcStore = useOidcStore()

    if (!oidcStore.isLogin) {
      return await Promise.resolve<HttpRequestResult<DeviceConfig[]>>({
        isSuccess: false,
        result: [],
        message: '用户未登录！'
      })
    }

    try {
      const response = await this.currentAxios.delete(this.baseUrl + '/api/device-configs/' + id, {
        headers: {
          Authorization: oidcStore.getBearerToken()
        }
      })
      return response.data as DefaultHttpRequestResult
    } catch (error) {
      console.error(error)
      return await Promise.resolve<DefaultHttpRequestResult>({
        isSuccess: false,
        message: '删除节点配置时错误！'
      })
    }
  }

  // 插入一个设备节点配置
  public async insertDeviceConfigAsync(
    newConfig: DeviceConfig & {
      nodeId: string
    }
  ) {
    const oidcStore = useOidcStore()

    if (!oidcStore.isLogin) {
      return await Promise.resolve<HttpRequestResult<DeviceConfig[]>>({
        isSuccess: false,
        result: [],
        message: '用户未登录！'
      })
    }

    try {
      const response = await this.currentAxios.post(
        this.baseUrl + '/api/device-configs',
        newConfig,
        {
          headers: {
            Authorization: oidcStore.getBearerToken()
          }
        }
      )
      return response.data as DefaultHttpRequestResult
    } catch (error) {
      console.error(error)
      return await Promise.resolve<DefaultHttpRequestResult>({
        isSuccess: false,
        message: '添加节点配置时错误！'
      })
    }
  }

  /*
   * 获取节点配置信息
   */
  public async getDeviceConfigsAsync(nodeId: string): Promise<HttpRequestResult<DeviceConfig[]>> {
    const oidcStore = useOidcStore()

    if (!oidcStore.isLogin) {
      return await Promise.resolve<HttpRequestResult<DeviceConfig[]>>({
        isSuccess: false,
        result: [],
        message: '用户未登录！'
      })
    }

    try {
      const response = await this.currentAxios.get(this.baseUrl + '/api/device-configs/' + nodeId, {
        headers: {
          Authorization: oidcStore.getBearerToken()
        }
      })
      return response.data as HttpRequestResult<DeviceConfig[]>
    } catch (error) {
      console.error(error)
      return await Promise.resolve<HttpRequestResult<DeviceConfig[]>>({
        isSuccess: false,
        result: [],
        message: '获取节点配置错误！'
      })
    }
  }

  // 获取所有节点
  public async getIdsAsync(): Promise<HttpRequestResult<string[]>> {
    const oidcStore = useOidcStore()

    if (!oidcStore.isLogin) {
      return await Promise.resolve<HttpRequestResult<string[]>>({
        isSuccess: false,
        result: [],
        message: '用户未登录！'
      })
    }

    try {
      const response = await this.currentAxios.get(this.baseUrl + '/api/nodes/ids', {
        headers: {
          Authorization: oidcStore.getBearerToken()
        }
      })

      return response.data as HttpRequestResult<string[]>
    } catch (error) {
      console.error(error)
      return await Promise.resolve<HttpRequestResult<string[]>>({
        isSuccess: false,
        result: [],
        message: '获取节点错误！'
      })
    }
  }
}
